package com.dg.river.core.view.dialog;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Typeface;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import com.dg.river.R;
import com.dg.river.core.view.wheel.ISelectTimeCallback;
import com.dg.river.core.view.wheel.NumericWheelAdapter;
import com.dg.river.core.view.wheel.WheelView;

import java.util.Arrays;
import java.util.List;

/**
 * Created by hy on 2023/04/21
 * Description : 选择时间
 */
public class ChooseDateDialog extends Dialog {

    private static ChooseDateDialog dialog;

    private static boolean isDismiss = false;

    private Context mContext;

    private String title;

    private OnClickBtnListener onClickBtnListener;

    private int year, month, day;

    private boolean cancel;

    private WheelView wv_year;
    private WheelView wv_month;
    private WheelView wv_day;

    private ISelectTimeCallback mSelectChangeCallback;

    private static final int DEFAULT_START_YEAR = 1900;
    private static final int DEFAULT_END_YEAR = 2100;
    private static final int DEFAULT_START_MONTH = 1;
    private static final int DEFAULT_END_MONTH = 12;
    private static final int DEFAULT_START_DAY = 1;
    private static final int DEFAULT_END_DAY = 31;

    private int startYear = DEFAULT_START_YEAR;
    private int endYear = DEFAULT_END_YEAR;
    private int startMonth = DEFAULT_START_MONTH;
    private int endMonth = DEFAULT_END_MONTH;
    private int startDay = DEFAULT_START_DAY;
    private int endDay = DEFAULT_END_DAY; //表示31天的
    private int currentYear;

    public ChooseDateDialog(@NonNull Context context) {
        super(context);
        this.mContext = context;
    }

    /**
     * 设置选择回调
     *
     * @param mSelectChangeCallback
     */
    public void setSelectChangeCallback(ISelectTimeCallback mSelectChangeCallback) {
        this.mSelectChangeCallback = mSelectChangeCallback;
    }

    /**
     * 设置标题
     *
     * @param title
     */
    public void setTitle(String title) {
        this.title = title;
    }

    public interface OnClickBtnListener {

        void onConfirm(ChooseDateDialog dialog);

        void onCancel(ChooseDateDialog dialog);

        void onOutside(ChooseDateDialog dialog);
    }

    /**
     * 设置点击事件
     *
     * @param onClickBtnListener
     */
    public void setOnClickBtnListener(OnClickBtnListener onClickBtnListener) {
        this.onClickBtnListener = onClickBtnListener;
    }

    /**
     * 设置日期
     *
     * @param year
     * @param month
     * @param day
     */
    public void setDate(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    /**
     * 设置是否能够取消
     *
     * @param cancel
     */
    public void setCancel(boolean cancel) {
        this.cancel = cancel;
    }

    /**
     * 弹出自定义Dialog
     *
     * @return
     */
    public ChooseDateDialog showDialog() {
        dialog = new ChooseDateDialog(mContext);
        dialog.setContentView(R.layout.dialog_choose_date);
        // 按返回键是否取消
        dialog.setCancelable(cancel);
        dialog.setCanceledOnTouchOutside(cancel);
        WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
        lp.gravity = Gravity.BOTTOM;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        dialog.getWindow().setAttributes(lp);
        //设置该属性，dialog可以铺满屏幕
        dialog.getWindow().setBackgroundDrawable(null);

        // 设置标题
        TextView tvTitle = dialog.findViewById(R.id.tvTitle);
        tvTitle.setText(title);

        // 添加大小月月份并将其转换为list,方便之后的判断
        String[] months_big = {"1", "3", "5", "7", "8", "10", "12"};
        String[] months_little = {"4", "6", "9", "11"};

        final List<String> list_big = Arrays.asList(months_big);
        final List<String> list_little = Arrays.asList(months_little);

        currentYear = year;

        // 年
        wv_year = dialog.findViewById(R.id.year);
        wv_year.setAdapter(new NumericWheelAdapter(startYear, endYear));// 设置"年"的显示数据
        wv_year.setCurrentItem(year - startYear);// 初始化时显示的数据
        wv_year.setDividerColor(ContextCompat.getColor(getContext(), R.color.black_6f6f6f));
        wv_year.setLineSpacingMultiplier(3.0f);
        wv_year.setGravity(Gravity.CENTER);
        wv_year.setCyclic(false);
        wv_year.setTypeface(Typeface.DEFAULT_BOLD);

        // 月
        wv_month = dialog.findViewById(R.id.month);
        if (startYear == endYear) {//开始年等于终止年
            wv_month.setAdapter(new NumericWheelAdapter(startMonth, endMonth));
            wv_month.setCurrentItem(month + 1 - startMonth);
        } else if (year == startYear) {
            //起始日期的月份控制
            wv_month.setAdapter(new NumericWheelAdapter(startMonth, 12));
            wv_month.setCurrentItem(month + 1 - startMonth);
        } else if (year == endYear) {
            //终止日期的月份控制
            wv_month.setAdapter(new NumericWheelAdapter(1, endMonth));
            wv_month.setCurrentItem(month);
        } else {
            wv_month.setAdapter(new NumericWheelAdapter(1, 12));
            wv_month.setCurrentItem(month);
        }
        wv_month.setGravity(Gravity.CENTER);
        wv_month.setLineSpacingMultiplier(3.0f);
        wv_month.setCyclic(false);
        wv_month.setTypeface(Typeface.DEFAULT_BOLD);
        wv_month.setDividerColor(ContextCompat.getColor(getContext(), R.color.black_6f6f6f));

        // 日
        wv_day = dialog.findViewById(R.id.day);
        if (startYear == endYear && startMonth == endMonth) {
            if (list_big.contains(String.valueOf(month + 1))) {
                if (endDay > 31) {
                    endDay = 31;
                }
                wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
            } else if (list_little.contains(String.valueOf(month + 1))) {
                if (endDay > 30) {
                    endDay = 30;
                }
                wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
            } else {
                // 闰年
                if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                    if (endDay > 29) {
                        endDay = 29;
                    }
                    wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
                } else {
                    if (endDay > 28) {
                        endDay = 28;
                    }
                    wv_day.setAdapter(new NumericWheelAdapter(startDay, endDay));
                }
            }
            wv_day.setCurrentItem(day - startDay);
        } else if (year == startYear && month + 1 == startMonth) {
            // 起始日期的天数控制
            if (list_big.contains(String.valueOf(month + 1))) {
                wv_day.setAdapter(new NumericWheelAdapter(startDay, 31));
            } else if (list_little.contains(String.valueOf(month + 1))) {
                wv_day.setAdapter(new NumericWheelAdapter(startDay, 30));
            } else {
                // 闰年
                if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                    wv_day.setAdapter(new NumericWheelAdapter(startDay, 29));
                } else {
                    wv_day.setAdapter(new NumericWheelAdapter(startDay, 28));
                }
            }
            wv_day.setCurrentItem(day - startDay);
        } else if (year == endYear && month + 1 == endMonth) {
            // 终止日期的天数控制
            if (list_big.contains(String.valueOf(month + 1))) {
                if (endDay > 31) {
                    endDay = 31;
                }
                wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
            } else if (list_little.contains(String.valueOf(month + 1))) {
                if (endDay > 30) {
                    endDay = 30;
                }
                wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
            } else {
                // 闰年
                if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                    if (endDay > 29) {
                        endDay = 29;
                    }
                    wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
                } else {
                    if (endDay > 28) {
                        endDay = 28;
                    }
                    wv_day.setAdapter(new NumericWheelAdapter(1, endDay));
                }
            }
            wv_day.setCurrentItem(day - 1);
        } else {
            // 判断大小月及是否闰年,用来确定"日"的数据
            if (list_big.contains(String.valueOf(month + 1))) {
                wv_day.setAdapter(new NumericWheelAdapter(1, 31));
            } else if (list_little.contains(String.valueOf(month + 1))) {
                wv_day.setAdapter(new NumericWheelAdapter(1, 30));
            } else {
                // 闰年
                if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                    wv_day.setAdapter(new NumericWheelAdapter(1, 29));
                } else {
                    wv_day.setAdapter(new NumericWheelAdapter(1, 28));
                }
            }
            wv_day.setCurrentItem(day - 1);
        }
        wv_day.setGravity(Gravity.CENTER);
        wv_day.setLineSpacingMultiplier(3.0f);
        wv_day.setCyclic(false);
        wv_day.setTypeface(Typeface.DEFAULT_BOLD);
        wv_day.setTextSize(18);
        wv_day.setDividerColor(ContextCompat.getColor(getContext(), R.color.black_6f6f6f));

        // 添加"年"监听
        wv_year.setOnItemSelectedListener(index -> {
            int year_num = index + startYear;
            currentYear = year_num;
            int currentMonthItem = wv_month.getCurrentItem();//记录上一次的item位置
            // 判断大小月及是否闰年,用来确定"日"的数据
            if (startYear == endYear) {
                //重新设置月份
                wv_month.setAdapter(new NumericWheelAdapter(startMonth, endMonth));
                if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
                    currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
                    wv_month.setCurrentItem(currentMonthItem);
                }
                int monthNum = currentMonthItem + startMonth;
                if (startMonth == endMonth) {
                    //重新设置日
                    setReDay(year_num, monthNum, startDay, endDay, list_big, list_little);
                } else if (monthNum == startMonth) {
                    //重新设置日
                    setReDay(year_num, monthNum, startDay, 31, list_big, list_little);
                } else if (monthNum == endMonth) {
                    setReDay(year_num, monthNum, 1, endDay, list_big, list_little);
                } else {//重新设置日
                    setReDay(year_num, monthNum, 1, 31, list_big, list_little);
                }
            } else if (year_num == startYear) {//等于开始的年
                //重新设置月份
                wv_month.setAdapter(new NumericWheelAdapter(startMonth, 12));
                if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
                    currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
                    wv_month.setCurrentItem(currentMonthItem);
                }
                int month1 = currentMonthItem + startMonth;
                if (month1 == startMonth) {
                    //重新设置日
                    setReDay(year_num, month1, startDay, 31, list_big, list_little);
                } else {
                    //重新设置日
                    setReDay(year_num, month1, 1, 31, list_big, list_little);
                }
            } else if (year_num == endYear) {
                //重新设置月份
                wv_month.setAdapter(new NumericWheelAdapter(1, endMonth));
                if (currentMonthItem > wv_month.getAdapter().getItemsCount() - 1) {
                    currentMonthItem = wv_month.getAdapter().getItemsCount() - 1;
                    wv_month.setCurrentItem(currentMonthItem);
                }
                int monthNum = currentMonthItem + 1;

                if (monthNum == endMonth) {
                    //重新设置日
                    setReDay(year_num, monthNum, 1, endDay, list_big, list_little);
                } else {
                    //重新设置日
                    setReDay(year_num, monthNum, 1, 31, list_big, list_little);
                }

            } else {
                //重新设置月份
                wv_month.setAdapter(new NumericWheelAdapter(1, 12));
                //重新设置日
                setReDay(year_num, wv_month.getCurrentItem() + 1, 1, 31, list_big, list_little);
            }
            if (mSelectChangeCallback != null) {
                mSelectChangeCallback.onTimeSelectChanged();
            }
        });
        // 添加"月"监听
        wv_month.setOnItemSelectedListener(index -> {
            int month_num = index + 1;
            if (startYear == endYear) {
                month_num = month_num + startMonth - 1;
                if (startMonth == endMonth) {
                    //重新设置日
                    setReDay(currentYear, month_num, startDay, endDay, list_big, list_little);
                } else if (startMonth == month_num) {
                    //重新设置日
                    setReDay(currentYear, month_num, startDay, 31, list_big, list_little);
                } else if (endMonth == month_num) {
                    setReDay(currentYear, month_num, 1, endDay, list_big, list_little);
                } else {
                    setReDay(currentYear, month_num, 1, 31, list_big, list_little);
                }
            } else if (currentYear == startYear) {
                month_num = month_num + startMonth - 1;
                if (month_num == startMonth) {
                    //重新设置日
                    setReDay(currentYear, month_num, startDay, 31, list_big, list_little);
                } else {
                    //重新设置日
                    setReDay(currentYear, month_num, 1, 31, list_big, list_little);
                }
            } else if (currentYear == endYear) {
                if (month_num == endMonth) {
                    //重新设置日
                    setReDay(currentYear, wv_month.getCurrentItem() + 1, 1, endDay, list_big, list_little);
                } else {
                    setReDay(currentYear, wv_month.getCurrentItem() + 1, 1, 31, list_big, list_little);
                }
            } else {
                //重新设置日
                setReDay(currentYear, month_num, 1, 31, list_big, list_little);
            }
            if (mSelectChangeCallback != null) {
                mSelectChangeCallback.onTimeSelectChanged();
            }
        });
        // 添加"日"监听
        wv_day.setOnItemSelectedListener(index -> {
            if (mSelectChangeCallback != null) {
                mSelectChangeCallback.onTimeSelectChanged();
            }
        });

        wv_day.setTextSize(18);
        wv_month.setTextSize(18);
        wv_year.setTextSize(18);

        dialog.findViewById(R.id.tvConfirm).setOnClickListener(v -> {
            slideToDown(dialog.getWindow().findViewById(R.id.bottomDialogLayout), onClickBtnListener, 0);
        });

        dialog.findViewById(R.id.tvCancel).setOnClickListener(v -> {
            slideToDown(dialog.getWindow().findViewById(R.id.bottomDialogLayout), onClickBtnListener, 1);
        });
        isDismiss = false;
        dialog.show();
        slideToUp(dialog.getWindow().findViewById(R.id.bottomDialogLayout));
        return dialog;
    }

    private void setReDay(int year_num, int monthNum, int startD, int endD, List<String> list_big, List<String> list_little) {
        int currentItem = wv_day.getCurrentItem();
        if (list_big.contains(String.valueOf(monthNum))) {
            if (endD > 31) {
                endD = 31;
            }
            wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
        } else if (list_little.contains(String.valueOf(monthNum))) {
            if (endD > 30) {
                endD = 30;
            }
            wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
        } else {
            if ((year_num % 4 == 0 && year_num % 100 != 0)
                    || year_num % 400 == 0) {
                if (endD > 29) {
                    endD = 29;
                }
            } else {
                if (endD > 28) {
                    endD = 28;
                }
            }
            wv_day.setAdapter(new NumericWheelAdapter(startD, endD));
        }
        if (currentItem > wv_day.getAdapter().getItemsCount() - 1) {
            currentItem = wv_day.getAdapter().getItemsCount() - 1;
            wv_day.setCurrentItem(currentItem);
        }
    }

    /**
     * 获取时间
     *
     * @return
     */
    public int[] getTime() {
        int[] timeInt = new int[3];
        if (currentYear == startYear) {
            if ((wv_month.getCurrentItem() + startMonth) == startMonth) {
                timeInt[0] = wv_year.getCurrentItem() + startYear;
                timeInt[1] = wv_month.getCurrentItem() + startMonth;
                timeInt[2] = wv_day.getCurrentItem() + startDay;
            } else {
                timeInt[0] = wv_year.getCurrentItem() + startYear;
                timeInt[1] = wv_month.getCurrentItem() + startMonth;
                timeInt[2] = wv_day.getCurrentItem() + 1;
            }
        } else {
            timeInt[0] =wv_year.getCurrentItem() + startYear;
            timeInt[1] = wv_month.getCurrentItem() + 1;
            timeInt[2] = wv_day.getCurrentItem() + 1;
        }
        return timeInt;
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        if (isOutOfBounds(getContext(), event)) {
            if (!isDismiss) {
                isDismiss = true;
            }
        }
        return false;
    }

    private boolean isOutOfBounds(Context context, MotionEvent event) {
        final int x = (int) event.getX();
        final int y = (int) event.getY();
        final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
        final View decorView = getWindow().getDecorView();
        return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop))
                || (y > (decorView.getHeight() + slop));
    }

    /**
     * 弹出动画
     *
     * @param view
     */
    public static void slideToUp(View view) {
        Animation slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
                1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
        slide.setDuration(300);
        slide.setFillAfter(true);
        slide.setFillEnabled(true);
        view.startAnimation(slide);

        slide.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {

            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    /**
     * 弹回动画
     *
     * @param view
     */
    public static void slideToDown(View view, OnClickBtnListener onClickBtnListener, int tag) {
        Animation slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
                .0f, Animation.RELATIVE_TO_SELF, 1.0f);
        slide.setDuration(200);
        slide.setFillAfter(true);
        slide.setFillEnabled(true);
        view.startAnimation(slide);
        slide.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (tag == 0) {
                    onClickBtnListener.onConfirm(dialog);
                } else if (tag == 1) {
                    onClickBtnListener.onCancel(dialog);
                } else if (tag == -1) {
                    onClickBtnListener.onOutside(dialog);
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }
}
